package com.wolfking.demo.nio.file;

import java.io.File;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Stack;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;

public class CopyDir {
    public static void main(String[] args) throws Exception {
        String src = "C:\\work";
        String target = "H:\\work";
        File srcDir = new File(src);
        File targetrDir = new File(target);
        Stream<Path> walk = Files.walk(Paths.get(src));
        int count = (int)walk.count();
        CountDownLatch countDownLatch = new CountDownLatch(count);
        walk = Files.walk(Paths.get(src));
        long start = System.currentTimeMillis();
        ThreadPoolExecutor executor = new ThreadPoolExecutor(15,15,10,TimeUnit.SECONDS,new LinkedBlockingQueue<>());
        walk.forEach(p -> {
            executor.execute(()->{
                File file = p.toFile();
                if (file.isFile()) {
                    long startMs = System.currentTimeMillis();
                    Stack<String> stack = new Stack<>();
                    do {
                        stack.add(file.getName());
                    } while (!(file = file.getParentFile()).equals(srcDir));
                    String path = "";
                    while (!stack.isEmpty()) {
                        path = path + File.separator + stack.pop();
                    }
                    path = path.substring(1);
                    try {
                        FileChannel readChannel = FileChannel.open(Paths.get(p.toFile().getAbsolutePath()), StandardOpenOption.READ);
                        File targetFile = new File(targetrDir.getAbsolutePath() + File.separator + path);
                        try{
                            if (!targetFile.exists()) {
                                if (!targetFile.getParentFile().exists()) {
                                    targetFile.getParentFile().mkdirs();
                                }
                                targetFile.createNewFile();
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                        FileChannel writeChannel = FileChannel.open(targetFile.toPath(), StandardOpenOption.WRITE);
                        readChannel.transferTo(0, readChannel.size(), writeChannel);
                        readChannel.close();
                        writeChannel.close();
//                        System.out.println("copy: " + p.toFile().getAbsolutePath() + " 成功,大小:" + p.toFile().length() / 1024 / 1024 + "m，用时："
//                                + (System.currentTimeMillis() - startMs) + "ms");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                countDownLatch.countDown();
            });
        });
        countDownLatch.await();
        executor.shutdown();
        System.out.println(System.currentTimeMillis() - start);
    }
}
